package com.enlighten.coinDataFetcher;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

public class ConcentricCircleDrawer {

	private static final Color BASECOLOR = Color.WHITE;
	private int radius;
	private int squaredRadius;
	private Color currentColor;
	private int currentRadius;
	private List<BufferedImage> bufferedImages = new ArrayList<BufferedImage>();
	private BufferedImage finalBufferedImage;

	public ConcentricCircleDrawer(int radius) {
		this.radius = radius;
		if ( radius % 2 == 0 )
			this.radius++;
		squaredRadius = radius*radius;
		int imgSize = getImageSize();
		finalBufferedImage = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB);
		finalBufferedImage.getGraphics().setColor(BASECOLOR);
		finalBufferedImage.getGraphics().fillRect(0, 0, imgSize, imgSize);
	}

	public static void main(String[] args) {
		ConcentricCircleDrawer circleDrawer = new ConcentricCircleDrawer(250);
		Color currentColor = Color.BLUE;
		for(int i = 10; i < 251 ; i++){
			circleDrawer.setCurrentRadiusAndColor(i,currentColor);
			circleDrawer.draw("");
			currentColor = getNextColor(currentColor);
			
		}
		circleDrawer.merge();
		circleDrawer.saveImage("experiment2.png");
		circleDrawer.drawUsingAPI("experiment3.png");
	}

	private void drawUsingAPI(String string) {
		int imgSize = getImageSize();
		Color currentColor = Color.BLUE;
		BufferedImage sampleImage = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB);
		Graphics2D createGraphics = sampleImage.createGraphics();
		createGraphics.setColor(BASECOLOR);
		createGraphics.fillRect(0, 0, imgSize, imgSize);
		for(int i = 10; i < 251 ; i++){
			createGraphics.setColor(currentColor);
			createGraphics.drawOval(radius-i, radius-i, 2*i, 2*i);
			currentColor = getNextColor(currentColor);
		}
		try {
			ImageIO.write(sampleImage, "PNG", new File(string));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static Color getNextColor(Color currentColor) {
		if ( currentColor == Color.PINK )
			return Color.blue;
		if ( currentColor == Color.gray )
			return Color.PINK;
		if ( currentColor == Color.orange )
			return Color.gray;
		if ( currentColor == Color.green )
			return Color.orange;
		if ( currentColor == Color.blue )
			return Color.green;
		return currentColor;
	}

	private void merge() {
		int nonPainted = 0;
		for(BufferedImage image:bufferedImages){
			nonPainted = 0;
			for(int i=0; i < image.getHeight(); i++){
				for(int j=0; j < image.getWidth(); j++){
					Color oldColor = new Color(finalBufferedImage.getRGB(j, i));
					Color newColor = new Color(image.getRGB(j, i));
					if ( newColor.equals(BASECOLOR) ){
						finalBufferedImage.setRGB(j, i, oldColor.getRGB());
					}else{
						if ( oldColor.equals(BASECOLOR) ){
							finalBufferedImage.setRGB(j, i, newColor.getRGB());
						}else{
							finalBufferedImage.setRGB(j, i, Color.RED.getRGB());
						}
					}
					if ( finalBufferedImage.getRGB(j, i) == BASECOLOR.getRGB() )
						nonPainted++;
				}
			}
		}
		System.out.println("Non painted = "+nonPainted);
	}

	private void setCurrentRadiusAndColor(int radius, Color currentColor) {
		currentRadius = radius;
		this.currentColor = currentColor;
	}

	private void draw(String filename) {
		int imgSize = getImageSize();
		BufferedImage bufferedImage = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB);
		for(int i=0; i < imgSize ; i++)
			for(int j=0; j < imgSize ; j++){
				int ni = i - radius + currentRadius;
				int nj = j - radius + currentRadius;
//				Color imageColor = new Color(bufferedImage.getRGB(i, j));
//				Color newColor = new Color(getColorFor(currentRadius,ni,nj));
//				bufferedImage.setRGB(i, j, mergeColors(imageColor,newColor));
				bufferedImage.setRGB(i, j, getColorFor(currentRadius,ni,nj));
			}
		
		bufferedImages.add(bufferedImage);
	}

	private void saveImage(String filename) {
		try {
			ImageIO.write(finalBufferedImage, "PNG", new File(filename));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private int getColorFor(int currentRadius, int i, int j) {
		int translatedX = i - currentRadius;
		int translatedY = j - currentRadius;
		int squaredDistance = translatedX*translatedX + translatedY*translatedY;
		if ( shouldPaint(squaredDistance, currentRadius*currentRadius, currentRadius) )
			return currentColor.getRGB();
		return BASECOLOR.getRGB();
	}

	private boolean shouldPaint(int squaredDistance, int squaredRadius, int currentRadius) {
//		return squaredDistance == squaredRadius && (currentRadius+1)*(currentRadius+1) > squaredDistance;
//		return (squaredDistance >= squaredRadius - currentRadius + 1) &&
//				(squaredDistance <= squaredRadius + currentRadius);
		return (squaredDistance >= ((currentRadius-1)*(currentRadius-1)) + currentRadius) &&
				(squaredDistance <= squaredRadius + currentRadius);
//		return (squaredDistance >= squaredRadius - currentRadius + 1/currentRadius) && (squaredDistance < squaredRadius + currentRadius - 1/currentRadius);
//		return (squaredDistance > squaredRadius - currentRadius + 1/4) && (squaredDistance < squaredRadius + currentRadius + 1/4);
//		return ((currentRadius + currentRadius - 1) / 2 ) <= Math.sqrt(squaredDistance) &&
//				Math.sqrt(squaredDistance) < ((currentRadius + currentRadius + 1) / 2 );
//		return currentRadius - 1 < Math.sqrt(squaredDistance) &&
//				Math.sqrt(squaredDistance) < currentRadius;
	}

	private int getImageSize() {
		return radius*2+1;
	}
}
